package com.example.myapplication.a_class.a04_expand

import android.content.Context
import android.widget.Toast
import com.example.myapplication.a_class.a04_expand.bean.FatherBean
import com.example.myapplication.a_class.a04_expand.bean.SonBean

/**
 * 扩展函数笔记
 * 1.格式 fun 需要扩展的类或接口 .方法名() : 返回值（无返回值不写）{ 方法体}
 * 2.一般声明在统一文件的 class {} 外边，声明在里面只有本文件可以调用
 * 3.在同一个包下不需要倒包，否则需要倒包，包名.扩展方法名
 * 4.Java 直接调用：扩展方法所在文件名 + kt .扩展方法名，需要传递一个被扩展的类的对象
 */


//扩展函数
fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(this, message, duration).show()
}

/**
 * Bean 扩展函数
 */
fun FatherBean.getCodeAndMsg(): String {
    //this 代表要扩展的对象
    return "扩展函数: code: ${this.code}  msg:${this.msg}"
}


/**
 * 扩展函数是静态分发的，即他们不是根据接收者类型的虚方法。
 * 这意味着调用的扩展函数是由函数调用所在的表达式的类型来决定的， 而不是由表达式运行时求值结果决定的
 */
fun FatherBean.getName() : String{
    return "fatherName"
}

fun SonBean.getName() :String{
    return "sonName"
}

fun SonBean.getClazzName(bean:FatherBean){
    //输出都是 fatherName
    println(bean.getName())
}


/**
 * 注意可以为可空的接收者类型定义扩展。这样的扩展可以在对象变量上调用， 即使其值为 null，并且可以在函数体内检测 this == null，
 * 这能让你在没有检测 null 的时候调用 Kotlin 中的toString()：检测发生在扩展函数的内部。
 */
fun SonBean?.toString(): String {

    if (this == null) return "null"

    // 空检测之后，“this”会自动转换为非空类型，所以下面的 toString()
    // 解析为 Any 类的成员函数
    return toString()

}


//扩展属性  不能直接操作 extend 没太理解
//var Bean.extend : Int
//    get() {
//        return age * 2
//    }
//    set(value) { age = value}